package com.whfc.ms.queue;

import com.whfc.base.entity.AppMessage;
import com.whfc.base.service.MessageService;
import com.whfc.common.constant.QueueConst;
import com.whfc.common.enums.AppMessageType;
import com.whfc.common.enums.AppWarnMsgChannel;
import com.whfc.common.util.JSONUtil;
import com.whfc.entity.dto.msg.AppMsgToUserDTO;
import com.whfc.entity.dto.msg.PushMsgDTO;
import com.whfc.ms.redis.StashMsMsgRedisDao;
import com.whfc.ms.websocket.WebSocketSessionManager;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2019/12/2 11:59
 */
@Component
public class PushMsgQueueMessageListener {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WebSocketSessionManager sessionManager;

    @Autowired
    private StashMsMsgRedisDao stashMsgRedisDao;

    @DubboReference(interfaceClass = MessageService.class, version = "1.0.0")
    private MessageService messageService;

    @RabbitListener(queues = QueueConst.PUSH_MS)
    public void process(String textMsg) {
        logger.info("push_ms_listener,{}", textMsg);
        try {
            PushMsgDTO pushMsgDTO = JSONUtil.parseObject(textMsg, PushMsgDTO.class);
            List<Integer> msgChannelList = pushMsgDTO.getMsgChannelList();
            List<AppMsgToUserDTO> toUserList = pushMsgDTO.getToUserList();
            if (msgChannelList != null && msgChannelList.contains(AppWarnMsgChannel.MS.value())) {
                //消息分发
                AppMessage srcMessage = new AppMessage();
                srcMessage.setDeptId(pushMsgDTO.getDeptId());
                srcMessage.setTime(pushMsgDTO.getTime());
                srcMessage.setTitle(pushMsgDTO.getTitle());
                srcMessage.setContent(pushMsgDTO.getContent());
                srcMessage.setModuleType(pushMsgDTO.getModuleType());
                srcMessage.setMsgObjectId(pushMsgDTO.getMsgObjectId());
                srcMessage.setMsgType(AppMessageType.SERVICE.value());
                srcMessage.setMsgChannel(AppWarnMsgChannel.MS.value());

                List<AppMessage> messageList = new ArrayList<>(toUserList.size());
                for (AppMsgToUserDTO toUserDTO : toUserList) {
                    AppMessage message = this.copy(srcMessage);
                    message.setToUserId(toUserDTO.getUserId());
                    message.setToUserName(toUserDTO.getNickName());
                    message.setToUserPhone(toUserDTO.getPhone());
                    messageList.add(message);
                }

                //消息存储
                if (messageList.size() > 0) {
                    logger.info("生成报警消息:ms:::::{}", JSONUtil.toString(messageList));
                    messageService.addMessage(messageList);
                }

                //消息推送
                Integer ruleType = pushMsgDTO.getRuleType();
                String triggerObjectId = pushMsgDTO.getTriggerObjectId();
                for (AppMessage msg : messageList) {
                    this.sendMsg(msg, ruleType, triggerObjectId);
                }
            }

        } catch (Exception ex) {
            logger.error("push_ms_listener,推送消息失败", ex);
        }
    }

    /**
     * 后台消息
     *
     * @param msg
     */
    private void sendMsg(AppMessage msg, Integer ruleType, String triggerObjectId) {
        try {
            PushMsgDTO msgDTO = this.translate(msg);
            msgDTO.setTriggerObjectId(triggerObjectId);
            msgDTO.setRuleType(ruleType);
            String textMsg = JSONUtil.toString(msgDTO);
            WebSocketSession session = sessionManager.getSession(String.valueOf(msg.getToUserId()));
            if (session != null && session.isOpen()) {
                session.sendMessage(new TextMessage(textMsg));
                logger.info("push_ms_listener,推送消息:{}", textMsg);
            } else {
                stashMsgRedisDao.setStashMsg(msg.getToUserId(), msgDTO);
                logger.info("push_ms_listener,用户不在线将消息转存:{}|{}", textMsg);
            }
        } catch (Exception ex) {
            logger.error("push_ms_listener,推送消息失败", ex);
        }

    }

    /**
     * 拷贝消息对象
     *
     * @param message
     * @return
     */
    private AppMessage copy(AppMessage message) {
        AppMessage desMessage = new AppMessage();
        BeanUtils.copyProperties(message, desMessage);
        desMessage.setId(null);
        desMessage.setUpdateTime(null);
        desMessage.setCreateTime(null);
        return desMessage;
    }

    /**
     * 转换推送消息dto
     *
     * @param message
     * @return
     */
    private PushMsgDTO translate(AppMessage message) {
        PushMsgDTO msgDTO = new PushMsgDTO();
        msgDTO.setTitle(message.getTitle());
        msgDTO.setContent(message.getContent());
        msgDTO.setTime(message.getTime());
        msgDTO.setModuleType(message.getModuleType());
        msgDTO.setMsgChannel(message.getMsgChannel());
        msgDTO.setToUserId(message.getToUserId());
        msgDTO.setToUserPhone(message.getToUserPhone());
        msgDTO.setToUserName(message.getToUserName());
        return msgDTO;
    }
}
